package com.gxa.dr2.service.impl;

import com.gxa.dr2.dto.Response;
import com.gxa.dr2.dto.ResultDTO;
import com.gxa.dr2.mapper.EmplMapper;
import com.gxa.dr2.mapper.PermissionMapper;
import com.gxa.dr2.pojo.Empl;
import com.gxa.dr2.pojo.Menu;
import com.gxa.dr2.pojo.Permission;
import com.gxa.dr2.pojo.Role;
import com.gxa.dr2.service.LoginService;
import com.gxa.dr2.util.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class LoginServiceImpl implements LoginService {


    @Autowired
    @SuppressWarnings("all")
    private EmplMapper mapper;

    @Resource
    private PermissionMapper permissionMapper;

    /**
     * 登录的方法
     * @param empl
     * @return
     */
    @Override
    public ResultDTO login(Empl empl, HttpSession session) {
        // 数据校验
        // 查询数据库
        Empl dbEmpl = mapper.findByCode(empl);
        // 判断员工数据是否为null
        if (dbEmpl == null) {
            // 说明员工不存在
            return Response.error(1001, "该员工不存在！");
        }
        // 校验密码
        // 将数据库保存的密码和传递过来的密码进行比对
        // 数据库的密码是加过密的
        // 传递过来的密码是没有加密的
        // 将数据库的密码和传递过来的密码加密之后进行比对
        if (!dbEmpl.getEmplPwd().equals(MD5Util.MD55(empl.getEmplPwd()))) {
            return Response.error(1001, "密码错误！");
        }
        // 判断状态
        if (!dbEmpl.getEmplStatus().equals(1)) {
            return Response.error(1001, "状态异常！请联系超级管理员！");
        }
        // 登录成功
        // 将用户名存放session对象中
        session.setAttribute("emplId", dbEmpl.getEmplId());
        session.setAttribute("emplName", dbEmpl.getEmplName());
        session.setAttribute("emplCode", dbEmpl.getEmplCode());
        session.setAttribute("deptName", dbEmpl.getDept().getDeptName());
        session.setAttribute("roles", getRoles(dbEmpl));
        session.setAttribute("status", dbEmpl.getEmplStatus());
        session.setAttribute("createTime", dbEmpl.getCreateTime());
        session.setAttribute("phone", dbEmpl.getEmplPhone());
        // 保存菜单数据
        session.setAttribute("menus", getMenus(dbEmpl));
        // 修改登录时间
        mapper.update(new Empl(dbEmpl.getEmplId(), new Timestamp(System.currentTimeMillis())));
        return Response.success("登录成功！");
    }

    /**
     * 获取菜单数据
     * @param empl
     * @return
     */
    private List<Menu> getMenus(Empl empl){
        return transMenu(getPermission(empl));
    }

    /**
     * 将权限数据转换成菜单数据
     * @param permissions
     * @return
     */
    private List<Menu> transMenu(List<Permission> permissions){
        // 先处理一级菜单
        List<Menu> menus = new ArrayList<>();
        for (Permission permission : permissions) {
            // 判断一级菜单
            if (permission.getParentId().equals(0) && permission.getIsMenu().equals(1) && permission.getPermissionLevel().equals(1)) {
                menus.add(new Menu(
                        permission.getPermissionId(),
                        permission.getPermissionName(),
                        permission.getPermissionUrl(),
                        permission.getPermissionLevel()));
            }
        }

        // 处理二级菜单
        // 子级菜单的parentId 等于 一级菜单的ID
        for (Menu menu : menus) {
            // 准备一个二级菜单容器
            List<Menu> subMenus = new ArrayList<>();
            for (Permission permission : permissions) {
                // 是判断是否是二级菜单
                if (permission.getPermissionLevel().equals(2) && permission.getIsMenu().equals(1) && permission.getParentId().equals(menu.getMenuId())) {
                    subMenus.add(new Menu(
                            permission.getPermissionId(),
                            permission.getPermissionName(),
                            permission.getPermissionUrl(),
                            permission.getPermissionLevel()));
                }
            }

            // 设置二级菜单那
            menu.setSubMenus(subMenus);
        }

        return menus;
    }


    /**
     * 获取权限数据, 且去重
     * @param empl
     * @return
     */
    private List<Permission> getPermission(Empl empl){
        // 超级管理员拥有所有的权限
        List<Permission> permissions = new ArrayList<>();
        Set<Permission> permissionSet = new HashSet<>();
        if (isSuper(empl)) {
            // 如果时超级管理员， 需要查询出所有的权限
            permissionSet.addAll(permissionMapper.findAll());
        }else {
            // 如果时非超级管理员， 直接从员工里面获取即可
            for (Role role : empl.getRoles()) {
                permissionSet.addAll(role.getPermissions());
            }
        }
        permissions.addAll(permissionSet);
        return permissions;
    }


    /**
     * 判断是否时超级管理员
     * @param empl
     * @return
     */
    private Boolean isSuper(Empl empl){
        if (empl.getRoles() == null || empl.getRoles().size() == 0) {
            return false;
        }
        // 获取员工的角色信息
        for (Role role : empl.getRoles()) {
            if ("ADMIN".equals(role.getRoleCode())) {
                return true;
            }
        }
        return false;
    }



    /**
     * 获取角色字符串
     * @param empl
     * @return
     */
    private String getRoles(Empl empl){
        List<Role> roles = empl.getRoles();
        String res = "";
        for (Role role : roles) {
            res += role.getRoleName()+",";
        }
        return res.substring(0, res.length()-1);
    }
}
